from executor.rows import Rows
from executor.range import Range

import pandas as pd


class Executor:
    def __init__(self, x, kde, reg, window_size):
        self.x = x
        self.kde = kde
        self.reg = reg
        self.window_size = window_size
        self.total_size = len(x)
        self.rows = Rows()
        self.range = Range()

    def cal_relerr(self, answer_file_path, result_list):
        standard_result = pd.read_csv(answer_file_path)['result']
        standard_result = standard_result.values
        relative_error = (abs(standard_result - result_list) / standard_result).mean() * 100
        print("relative error is: {}%".format(relative_error))

    def calculate(self, func, mode='range'):
        result_list = []
        if mode == 'range':
            if func.lower() == "count":
                result_list = self.range.count(self.kde, self.x, self.window_size, self.total_size)
            elif func.lower() == "sum":
                result_list = self.range.sum(self.kde, self.x, self.window_size)
            elif func.lower() == "avg":
                result_list = self.range.avg(self.kde, self.x, self.window_size)
            elif func.lower() == "cume_dist":
                self.range.cume_dist(self.kde, self.x)
            else:
                print("Aggregate function " + func + " is not implemented yet!")
        elif mode == 'rows':
            if func.lower() == "sum":
                result_list = self.rows.sum(self.reg, self.x, self.window_size)
            elif func.lower() == "avg":
                result_list = self.rows.avg(self.reg, self.x, self.window_size)
            else:
                print("Aggregate function " + func + " is not implemented yet!")

        answer_file_path = '../standard_result/{}_{}1g.csv'.format(mode, func)
        self.cal_relerr(answer_file_path, result_list)

        return result_list
